package cn.antcore.resources.spring;

import cn.antcore.resources.Constants;
import cn.antcore.resources.config.GlobalConfig;
import cn.antcore.resources.encrypt.ResourceEncrypt;
import cn.antcore.resources.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnumerableCompositePropertySource;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;

import java.util.*;

/**
 * Created By Hong on 2018/8/2
 **/
public abstract class AbstractEnvironment implements EnvironmentPostProcessor {

    /**
     * 数据源名
     */
    private String[] source = new String[0];

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment configurableEnvironment, SpringApplication springApplication) {
        this.writeToGlobalConfig(configurableEnvironment);
        //从Spring Environment中读取${ant.core.config.source}配置源
        String source = configurableEnvironment.getProperty(Constants.ANT_CORE_CONFIG_SOURCE);
        if (StringUtils.isEmpty(source)) {
            //Spring中不存在，就重新读取默认的配置文件
            source = GlobalConfig.get().getValue(Constants.ANT_CORE_CONFIG_SOURCE);
        }
        if (StringUtils.isNotEmpty(source)) {
            this.source = source.split(",");
        }
    }

    /**
     * 将SpringConfig配置写入到GlobalConfig中
     *
     * @param configurableEnvironment ConfigurableEnvironment
     */
    private void writeToGlobalConfig(ConfigurableEnvironment configurableEnvironment) {
        Iterator<PropertySource<?>> iterator = configurableEnvironment.getPropertySources().iterator();
        while (iterator.hasNext()) {
            PropertySource source = iterator.next();
            //资源Class名字
            String sourceClassName = source.getSource().getClass().getName();
            if (source instanceof Map) {
                //是Map直接添加进SelfConfig中
                Map map = (Map) source.getSource();
                if (map != null) {
                    GlobalConfig.putAll(ResourceEncrypt.value(map));
                }
            } else if (sourceClassName.equals(Properties.class.getName())) {
                //是Properties属性直接添加进SelfConfig中
                Properties properties = (Properties) source.getSource();
                if (properties != null) {
                    GlobalConfig.putAll(ResourceEncrypt.value(properties));
                }
            } else if (sourceClassName.equals(ArrayList.class.getName())) {
                List list = (List) source.getSource();
                if (list != null && !list.isEmpty()) {
                    for (Object item : list) {
                        //如果集合中是EnumerableCompositePropertySource元素；则将EnumerableCompositePropertySource添加进SelfConfig中
                        if (item instanceof EnumerableCompositePropertySource) {
                            Map<Object, Object> map = new HashMap<>();
                            EnumerableCompositePropertySource enumerableCompositePropertySource = (EnumerableCompositePropertySource) item;
                            String[] result = enumerableCompositePropertySource.getPropertyNames();
                            for (String key : result) {
                                map.put(key, enumerableCompositePropertySource.getProperty(key));
                            }
                            GlobalConfig.putAll(ResourceEncrypt.value(map));
                        }
                    }
                }
            }
        }
    }

    public String[] getSource() {
        return source;
    }
}
